#ifndef _TYPE_TRAITS_H_
#define _TYPE_TRAITS_H_

#include "typelist.hpp"

namespace Medved
{

typedef TYPELIST_4(unsigned char, unsigned short, unsigned int, unsigned long) UnsignedInts;
typedef TYPELIST_4(signed char, short, int, long) SignedInts;
typedef TYPELIST_2(char, bool) OtherInts;

typedef TYPELIST_3(float, double, long double) Floats;

namespace Private
{
	template <class T>
	struct UnConst
	{
		typedef T Result;
	};

	template <class T>
	struct UnConst<const T>
	{
		typedef T Result;
	};

	template <class T>
	struct UnVolatile
	{
		typedef T Result;
	};

	template <class T>
	struct UnVolatile<volatile T>
	{
		typedef T Result;
	};

}

template <class T>
struct TypeTraits
{
	typedef typename Private::UnConst<T>::Result RemoveConst;
	typedef typename Private::UnVolatile<T>::Result RemoveVolatile;
	typedef typename Private::UnConst<RemoveVolatile>::Result RemoveCV;
	
	enum
	{
		isUnsignedInt = IsInList<UnsignedInts, RemoveCV>::Result,
		isSignedInt = IsInList<SignedInts, RemoveCV>::Result,
		isOtherInt = IsInList<OtherInts, RemoveCV>::Result,
		isInt = isUnsignedInt || isSignedInt || isOtherInt,
		isFloat = IsInList<Floats, RemoveCV>::Result,
		isBuiltIn = isInt || isFloat
	};
};

}
#endif
